package com.yhy.consume.mq.listener;

import cn.hutool.json.JSONUtil;
import com.rabbitmq.client.Channel;
import com.yhy.common.rabbitmq.model.MessageData;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

@Slf4j
@Component
public class DLXConsumer {

    @SneakyThrows
    @RabbitHandler
    @RabbitListener(queues = "default.dlx.queue.1")
    public void handler1(MessageData<Map<String, Object>> messageData, Message message, Channel channel) {
        //  如果手动ACK,消息会被监听消费,但是消息在队列中依旧存在,如果 未配置 acknowledge-mode 默认是会在消费完毕后自动ACK掉
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        Map<String, Object> map = messageData.getData();
        log.info("handler1延迟队列，手动ACK，接收消息id: {}, 消息体: {}", messageData.getMessageId(), JSONUtil.parse(map));
        // 手动确认 multiple 批量是否
        channel.basicAck(deliveryTag, false);
    }

    @SneakyThrows
    @RabbitHandler
    @RabbitListener(queues = "default.dlx.queue.2")
    public void handler2(MessageData<Map<String, Object>> messageData, Message message, Channel channel) {
        //  如果手动ACK,消息会被监听消费,但是消息在队列中依旧存在,如果 未配置 acknowledge-mode 默认是会在消费完毕后自动ACK掉
        final long deliveryTag = message.getMessageProperties().getDeliveryTag();
        String messageId = message.getMessageProperties().getMessageId();
        final Map<String, Object> data = messageData.getData();
        log.info("handler2延迟队列，手动ACK，接收消息id: {}, 消息体: {}", messageId, JSONUtil.parse(data));
        // 手动确认 multiple 批量是否
        channel.basicAck(deliveryTag, false);

        // 手动拒绝。支持批量。 requeue 是否重新入队 true 重新入队, false 丢弃或进入死信队列
//        channel.basicNack(deliveryTag,false,false);
//
//        // 手动拒绝 requeue 是否重新入队 true 重新入队, false 丢弃或进入死信队列
//        channel.basicReject(deliveryTag,false);
//
//        // 是否恢复消息到消息队列，requeue true重新入队列，并且尽可能将之前接收到的消息投递给其他消费者，false则重新投递给自己
//        channel.basicRecover(false);
    }
}
